package code.structure.module.scene.view
{
	import code.main.App;
	import code.main.AppData;
	import code.structure.module.scene.SceneController;
	import code.structure.module.scene.manager.DiySceneManager;
	import code.structure.module.scene.manager.InfoSceneManager;
	import code.structure.module.scene.manager.NormalSceneManager;
	import code.structure.module.scene.model.SceneModel;
	import code.structure.module.scene.view.iso.WallIsoObject;
	import code.structure.module.scene.view.iso.WallMuralIsoObject;
	import code.structure.module.scene.view.iso.YIsoObject;
	import code.structure.module.scene.view.layer.CrackLayer;
	import code.structure.module.user.UserModel;
	import code.tools.bitmap.FrameDrive;
	import code.tools.traceLog.TraceLog;
	import code.untils.CommandNameConst;
	import code.untils.IsoStatusConst;
	import code.untils.SceneConfig;
	
	import com.patience.map.isometric.core.IObject;
	import com.patience.map.isometric.core.IsoMapInfo;
	import com.patience.map.isometric.core.IsoTryResult;
	import com.patience.map.isometric.core.IsoWorld;
	import com.patience.map.isometric.events.IsoMouseEvent;
	import com.patience.map.isometric.iso.IsoObject;
	import com.patience.map.isometric.pathfinding.YMapGrid;
	import com.patience.map.isometric.utils.IsoTypeConst;
	import com.patience.mvc.context.Command;
	
	import flash.display.Sprite;
	import flash.utils.Dictionary;
	
	/**
	 *项目中的世界 
	 * @author Yuri
	 * 
	 */
	public class YIsoWorld extends IsoWorld
	{
		private var TOP_PADDING:Number = 0;
		private var BOTTOM_PADDING:Number = 0;
		private var LEFT_PADDING:Number = 0;
		private var RIGHT_PADDING:Number = 0;
		
		private var _status:String = SceneConfig.SCENE_NORMAL;
		private var _controller:SceneController;
		
		private var _infoManager:InfoSceneManager;
		private var _diyManager:DiySceneManager;
		private var _normalManager:NormalSceneManager;
		private var _sceneModel:SceneModel;
		private var _userModel:UserModel;
		private var _sceneTipContainer:Sprite;
		
		private var _crackLayer:CrackLayer;
		private var _dropContainer:Sprite;
		
		/**
		 *鼠标层 
		 */
		//		private var _mouseLayer:Sprite;
		public function YIsoWorld()
		{
			super(SceneConfig.WORLD_X_NUM,SceneConfig.WORLD_Z_NUM,SceneConfig.WORLD_GRID_SIZE,true,SceneConfig.WORLD_AREA_LENGTH,SceneConfig.WORLD_AREA_LENGTH);
		}
		
		override public function init():void{
			super.init();
			_isCanDrag = true;
			_crackLayer = new CrackLayer();
			_sceneTipContainer = new Sprite();
			_dropContainer = new Sprite();
			_worldContainer.addChildAt(_crackLayer,2);
			_worldContainer.addChild(_sceneTipContainer);
			_worldContainer.addChild(_dropContainer);
			_infoManager = new InfoSceneManager(this);
			_diyManager = new DiySceneManager(this);
			_normalManager = new NormalSceneManager(this);
			_sceneTipContainer.mouseEnabled  = false;
		}
		
		/**
		 * 设置世界可控制其移动范围 
		 * @param sceneType
		 * @param scale
		 * 
		 */
		public function reSetContentRect(sceneType:int=0,scale:Number=1):void{
			width = App.appstage.stageWidth;
			height = App.appstage.stageHeight;
			if(sceneType==0){
				TOP_PADDING = SceneConfig.TOP_PADDING;
				BOTTOM_PADDING = SceneConfig.BOTTOM_PADDING;
				LEFT_PADDING = SceneConfig.LEFT_PADDING;
				RIGHT_PADDING = SceneConfig.RIGHT_PADDING;
			}else if(sceneType == 1){
				TOP_PADDING = SceneConfig.GM_TOP_PADDING;
				BOTTOM_PADDING = SceneConfig.GM_BOTTOM_PADDING;
				LEFT_PADDING = SceneConfig.GM_LEFT_PADDING;
				RIGHT_PADDING = SceneConfig.GM_RIGHT_PADDING;
			}
			setContentRect(TOP_PADDING,BOTTOM_PADDING,LEFT_PADDING,RIGHT_PADDING);
			moveContentXYtoCenterByGridPoint(SceneConfig.SCENE_CENTER_GRID_POINT);
		}
		
		public function initIsoMouseEvents():void{
			addEventListener(IsoMouseEvent.ISO_MOUSE_CLICK,onIsoMouseEventHandler);
			addEventListener(IsoMouseEvent.ISO_MOUSE_OUT,onIsoMouseEventHandler);
			addEventListener(IsoMouseEvent.ISO_MOUSE_OVER,onIsoMouseEventHandler);
			addEventListener(IsoMouseEvent.ISO_MOUSE_CLICK_SPACE,onIsoMouseEventHandler);
			addEventListener(IsoMouseEvent.ISO_MOUSE_MOVE,onIsoMouseEventHandler);
			
			addEventListener(IsoMouseEvent.ISO_MOUSE_MOVE_STOP,onIsoMouseEventHandler);
			
			addEventListener(IsoMouseEvent.ISO_MOUSE_DOWN_MOVE_START,onIsoMouseEventHandler);
			addEventListener(IsoMouseEvent.ISO_MOUSE_DOWN_MOVE_STOP,onIsoMouseEventHandler);
		}
		
		
		override public function mouseEventHandler(x:Number, y:Number, type:String,isLeftKeyDown:Boolean):void{
			super.mouseEventHandler(x,y,type,isLeftKeyDown);
		}
		
		protected function onIsoMouseEventHandler(e:IsoMouseEvent):void
		{
			var iso:YIsoObject = e.targetIsoObject as YIsoObject;
			switch(e.type){
				case IsoMouseEvent.ISO_MOUSE_OVER:
					//					TraceLog.showTrace("有对象鼠标OVER","世界场景点击测试");
					if(!iso.isResponseMouse) return;
					if(status == SceneConfig.SCENE_NORMAL){
						_normalManager.mouseOverIsoObject(iso,e.stageX,e.stageY);
					}else{
						iso.status = IsoStatusConst.ISO_STATUS_OVER;
					}
					break;
				case IsoMouseEvent.ISO_MOUSE_OUT:
					//					TraceLog.showTrace("有对象鼠标OUT","世界场景点击测试");
					if(!iso.isResponseMouse) return;
					if(status == SceneConfig.SCENE_NORMAL){
						_normalManager.mouseOutIsoObject(iso);
					}else{
						iso.status = IsoStatusConst.ISO_STATUS_NORMAL;
					}
					
					break;
				case IsoMouseEvent.ISO_MOUSE_CLICK:
					if(!iso.isResponseMouse){
						if(status == SceneConfig.SCENE_NORMAL){
							if(!iso.isUnlock || iso.isWalk){
								_normalManager.mouseSpaceClick(e.stageX, e.stageY);
							}
						}
						return;
					}
					TraceLog.showTrace("有对象被点到了","世界场景点击测试");
					if(status == SceneConfig.SCENE_DIY){
						_diyManager.selectDiyCurrentIso( iso);
					}else{
							_normalManager.mouseClickIsoObject(iso,e.stageX,e.stageY);
					}
					break;
				case IsoMouseEvent.ISO_MOUSE_CLICK_SPACE:
					TraceLog.showTrace("点到空地方","世界场景点击测试");
					if (status == SceneConfig.SCENE_NORMAL) {
						_normalManager.mouseSpaceClick(e.stageX, e.stageY);
					}
					break;
				case IsoMouseEvent.ISO_MOUSE_MOVE:
					if(status == SceneConfig.SCENE_NORMAL)
						_normalManager.mouseMoveIsoWorld(e.stageX,e.stageY);
					break;
				case IsoMouseEvent.ISO_MOUSE_DOWN_MOVE_START:
					FrameDrive.pause();
					break;
				case IsoMouseEvent.ISO_MOUSE_DOWN_MOVE_STOP:
					if(status == SceneConfig.SCENE_NORMAL){
						FrameDrive.play();
					}
					//通知拖动了场景
					controller.dispatch(new Command(CommandNameConst.COMMAND_DRAG_SCREEN));
					break;
				case IsoMouseEvent.ISO_MOUSE_MOVE_STOP:
					if(status == SceneConfig.SCENE_DIY){
						_diyManager.checkDiyStatusByMouseMoveStop(e.stageX,e.stageY);
					}
					break;
			}
		}
		
		override protected function worldMouseOutHandler(x:Number, y:Number):void{
			super.worldMouseOutHandler(x,y);
			_normalManager.clearCurrentTargetFocus();
		}
		
		override protected function worldMouseClickHandler(x:Number, y:Number):void{
			if(status == SceneConfig.SCENE_NORMAL){
				super.worldMouseClickHandler(x, y);
			}else if(status == SceneConfig.SCENE_DIY){
				if(_diyManager.currentDiyIsoObject){ //已经选中物品还在场景中
					_diyManager.checkDiyStatusByMouseClick(x,y);
				}else{
					super.worldMouseClickHandler(x,y);
				}
			}
		}
		
		override protected function worldMouseMoveHandler(x:Number, y:Number):void{
			if(status == SceneConfig.SCENE_NORMAL){
				super.worldMouseMoveHandler(x, y);
				if(AppData.isMyScene)
					checkLockArea(x, y);									//============================================ CYang
			}else if(status == SceneConfig.SCENE_DIY){
				if(_diyManager.currentDiyIsoObject){
					_diyManager.checkDiyStatusByMouseMove(x,y);
				}else{
					super.worldMouseMoveHandler(x,y);
				}
			}
		}
		
		/**
		 *刷新场景数据 
		 * @param d
		 * 
		 */
		public function refreshWorldSceneData(dic:Dictionary):void{
			_infoManager.refreshWorldSceneData(dic);
		}
		
		/**
		 * 移动场景通过世界中的一个坐标
		 * @param gridX
		 * @param gridZ
		 * 
		 */
		public function moveContentXYtoCenterByIsoPosition(isoPX:Number,isoPY:Number):void{
			contentX = width/2 - isoPX*scale;
			contentY = (height)/2 -isoPY*scale;
		}
		
		/**
		 *退出diy 
		 * 
		 */
		public function exitDiy():void{
			status = SceneConfig.SCENE_NORMAL;
		}
		
		/**
		 *检查一个场景元素放置情况 
		 * @param iso
		 * @return 
		 * 
		 */
		public function checkIsoObjectPlace(iso:IsoObject):IsoTryResult{
			var isoTry:IsoTryResult = tryHandlerObject(iso);
			if(iso as WallMuralIsoObject){ //墙上装饰物
				var index:int;
				var len:int = isoTry.crossIsoList.length;
				for(index = 0; index < len; index++)
				{
					var tempIsoObject:IsoObject = isoTry.crossIsoList[index];
					if((tempIsoObject as WallIsoObject && (tempIsoObject as WallIsoObject).isCanAttach)
						|| tempIsoObject as WallMuralIsoObject)
					{
						isoTry.isSucess = false;
						break;
					}else{
						isoTry.isSucess = true;
					}
				}
			}else if (iso.classify == IsoTypeConst.ISO_FLOOR_TYPE){
				isoTry.isSucess = true;
			}
			return isoTry;
		}
		
		override public function addToWorld(iObject:IObject,isNeedAddMapItem:Boolean = true):IObject{
			_infoManager.addToWorld(iObject);
			return super.addToWorld(iObject,isNeedAddMapItem);
		}
		
		override public function removeFromWorld(iObject:IObject,isClear:Boolean = true,isNeedRemoveMapItem:Boolean = true):void{
			_infoManager.removeFromWorld(iObject,isClear);
			super.removeFromWorld(iObject,isClear,isNeedRemoveMapItem);
		}
		
		/**
		 *设置物件层鼠标事件 
		 * @param isMouseEnable
		 * 
		 */
		public function set worldObjectLayerMouseEnable(isMouseEnable:Boolean):void{
			_objectContainer.mouseEnabled = isMouseEnable;
		}
		
		/**
		 *设置地板层鼠标事件 
		 * @param isMouseEnable
		 * 
		 */
		public function set worldFloorLayerMouseEnable(isMouseEnable:Boolean):void{
			_floorContainer.mouseEnabled = isMouseEnable;
		}
		
		/**
		 *设置物件层透明值 
		 * @param alpha
		 * 
		 */
		public function set worldObjectLayerAlpha(alpha:Number):void{
			_objectContainer.alpha = alpha;
		}
		
		/**
		 *当前世界状态 
		 */
		public function get status():String
		{
			return _status;
		}
		
		/**
		 * @private
		 */
		public function set status(value:String):void
		{
			if(value == status) return;
			_status = value;
			if(value == SceneConfig.SCENE_NORMAL){
				_diyManager.exit();
				showGrids(false);
				FrameDrive.play();
			}else if(value == SceneConfig.SCENE_DIY){
				FrameDrive.pause();
				_normalManager.exit();
				_diyManager.init();
				showGrids();
			}
			changeEffectByStatus();
			if(controller)
				controller.dispatch(new Command(CommandNameConst.COMMAND_SCENE_STATUS_CHANGE,value == SceneConfig.SCENE_NORMAL?0:1));
		}
		
		/**
		 *因场景状态的影响 
		 * 
		 */
		private function changeEffectByStatus():void{
			_infoManager.changeEffectByWorldStatus(status);
			if(status == SceneConfig.SCENE_NORMAL){
				isNeedFloorSort = false;
			}
			_normalManager.setGuideState(status == SceneConfig.SCENE_NORMAL);
		}
		
		/**
		 *通过id获取场景对象 
		 * @param key
		 * @return 
		 * 
		 */
		public function getIsoObjectById(key:String):YIsoObject{
			if(!key || key=="") return null;
			for each(var iso:YIsoObject in _mapInfo.allIsoObjectList){
				if(iso.id == key)
					return iso;
			}
			return null;
		}
		
		
		/**
		 *移除监听 
		 * 
		 */
		private function removeListeners():void{
			removeEventListener(IsoMouseEvent.ISO_MOUSE_CLICK,onIsoMouseEventHandler);
			removeEventListener(IsoMouseEvent.ISO_MOUSE_OUT,onIsoMouseEventHandler);
			removeEventListener(IsoMouseEvent.ISO_MOUSE_OVER,onIsoMouseEventHandler);
			removeEventListener(IsoMouseEvent.ISO_MOUSE_CLICK_SPACE,onIsoMouseEventHandler);
			
			removeEventListener(IsoMouseEvent.ISO_MOUSE_MOVE,onIsoMouseEventHandler);
			
			removeEventListener(IsoMouseEvent.ISO_MOUSE_MOVE_STOP,onIsoMouseEventHandler);
			
			removeEventListener(IsoMouseEvent.ISO_MOUSE_DOWN_MOVE_START,onIsoMouseEventHandler);
			removeEventListener(IsoMouseEvent.ISO_MOUSE_DOWN_MOVE_STOP,onIsoMouseEventHandler);
		}
		
		public function get diyManager():DiySceneManager
		{
			return _diyManager;
		}
		
		public function get controller():SceneController
		{
			return _controller;
		}
		
		public function set controller(value:SceneController):void
		{
			_controller = value;
			if(value){
				_sceneModel = _controller.sceneModel;
				_userModel = _controller.userModel;
			}
			if (_diyManager) _diyManager.controller = value;
			if (_normalManager) _normalManager.controller = value;
			if(_infoManager) _infoManager.controller = value;
		}
		
		/**
		 *正常状态下管理器 
		 */
		public function get normalManager():NormalSceneManager
		{
			return _normalManager;
		}
		
		public function get sceneTipContainer():Sprite
		{
			return _sceneTipContainer;
		}
		
		public function get mapInfo():IsoMapInfo{
			return _mapInfo;
		}
		
		public function get mapGrid():YMapGrid{
			return _mapGrid;
		}
		
		public function get infoManager():InfoSceneManager
		{
			return _infoManager;
		}
		
		/**
		 *掉落物层 
		 */
		public function get dropContainer():Sprite
		{
			return _dropContainer;
		}
		
		/**
		 *背景层 
		 * @return 
		 * 
		 */
		public function get bgContainer():Sprite{
			return _bgContainer;
		}
		
		/**
		 *夹缝层 （在地板层在物件层中间）  
		 */
		public function get crackLayer():CrackLayer
		{
			return _crackLayer;
		}
		/**
		 * 获取用户数据
		 */
		public function get userModel():UserModel 
		{
			return _userModel;
		}
		
		
		/**
		 *清空 
		 * 
		 */
		public function clear():void{
			removeListeners();
			tipContainerClear();
			_infoManager.clear();
			_diyManager.clear();
			_normalManager.clear();
			refresh();
		}
		
		/**
		 *容器清除  包含  
		 * 
		 */
		private function tipContainerClear():void{
			if(_sceneTipContainer){
				while(_sceneTipContainer.numChildren>0){
					_sceneTipContainer.removeChildAt(0);
				}
			}
		}
		
		
		
		/**
		 *是否允许拖动 
		 * @param value
		 * 
		 */
		public function set isCanDrag(value:Boolean):void{
			_isCanDrag = value;
		}
		
		
		
		/**
		 * 针对一个对象在周围环境中的排序 
		 * @param iso
		 * @param distance
		 * @param offsetX
		 * @param offsetZ
		 * 
		 */
		public function sortIsoObjectByAreaDistance(iso:YIsoObject,distance:int,offsetX:int=0,offsetZ:int=0):void{
			if(!iso) return ;
			var startX:int = iso.gridX + offsetX -distance;
			var startZ:int = iso.gridZ + offsetZ -distance;
			var endX:int = iso.gridX + offsetX +distance;
			var endZ:int = iso.gridZ + offsetZ+distance;
			var arr:Array = mapInfo.getRangleIsoList(startX,startZ,endX,endZ,iso.classify);
			if(arr.indexOf(iso)==-1) arr.push(iso);
			var count:int = arr.length;
			
			//先判断当前顺序排序
			var i:int = 0;
			var tempiso:YIsoObject;
			var index:int=-1;
			var sortArr:Array = [];
			
			var tempContainer:Sprite = iso.classify == IsoTypeConst.ISO_OBJECT_TYPE?_objectContainer:_floorContainer;
			//改对象的索引
			var isoIndex:int = tempContainer.getChildIndex(iso);
			sortArr = sortSomeIsoList(arr);
			index = sortArr.indexOf(iso);
			if(index !=-1){
				var tempIndex:int ;
				if(index==sortArr.length-1) {
					tempIndex = tempContainer.getChildIndex(sortArr[index])+1;
				}else{
					tempIndex = tempContainer.getChildIndex(sortArr[index+1])-1;
				}
			}else{
				return;
			}
			if(tempIndex>=tempContainer.numChildren)tempIndex = tempContainer.numChildren-1;
			if(tempIndex == isoIndex) return;
			tempContainer.setChildIndex(iso,tempIndex);
		}
		
		
		public function sortIsoObjectByAreaDistanceA(iso:YIsoObject,distance:int,offsetX:int=0,offsetZ:int=0):void{
			if(!iso) return ;
			var startX:int = iso.gridX + offsetX -distance;
			var startZ:int = iso.gridZ + offsetZ -distance;
			var endX:int = iso.gridX + offsetX +distance;
			var endZ:int = iso.gridZ + offsetZ+distance;
			var arr:Array = mapInfo.getRangleIsoList(startX,startZ,endX,endZ,iso.classify);
			var count:int = arr.length;
			
			//先判断当前顺序排序
			var i:int = 0;
			var tempiso:YIsoObject;
			var index:int=-1;
			var sortArr:Array = [];
			
			var tempContainer:Sprite = iso.classify == IsoTypeConst.ISO_OBJECT_TYPE?_objectContainer:_floorContainer;
			//改对象的索引
			var isoIndex:int = tempContainer.getChildIndex(iso);
			
			for(i=0;i<count;i++){
				tempiso = arr[i] as YIsoObject;
				if(!tempiso || tempiso == iso) continue;
				index = tempContainer.getChildIndex(tempiso);
				sortArr.push({"iso":tempiso,"index":index});
			}
			sortArr.sortOn("index",Array.NUMERIC);
			count = sortArr.length;
			
			// 对象高于数组中层级的索引
			var  limitTargetThanHighIndex:int = -1;
			//对象低于数组中层级的索引
			var limitTargetThanLowIndex:int = -1;
			
			var lowListIndex:int=-1;
			var upListIndex:int=-1;
			for(i=count-1;i>=0;i--){
				tempiso = sortArr[i].iso;
				var checkB:Boolean = sortFunB(iso,tempiso,offsetX,offsetZ);
				if(!checkB){ //对象层级高
					if(limitTargetThanHighIndex==-1){
						upListIndex = i;
						limitTargetThanHighIndex  = sortArr[i].index;
					}
				}else{
					limitTargetThanLowIndex =  sortArr[i].index;
					lowListIndex = i;
				}
			}
			if(count==0) return;
			var tempIndex:int;
			if(limitTargetThanHighIndex==-1){//没有比对象要低的层级情况
				tempIndex = sortArr[0].index - 1;
				if(tempIndex<0) tempIndex = 0;
				if(tempIndex!=isoIndex)
					tempContainer.setChildIndex(iso,tempIndex);
				return;
			}else if(limitTargetThanLowIndex==-1){ //没有有比对象层级要高的情况
				tempIndex  = sortArr[count-1].index+1;
				if(tempIndex>=tempContainer.numChildren)tempIndex = tempContainer.numChildren-1;
				if(tempIndex == isoIndex) return;
				tempContainer.setChildIndex(iso,tempIndex);
				return;
			}
			else {
				var templowIso:YIsoObject =  sortArr[lowListIndex].iso as YIsoObject;
				var tempupIso:YIsoObject =  sortArr[upListIndex].iso as YIsoObject;
				if(limitTargetThanLowIndex>limitTargetThanHighIndex){
					tempIndex = limitTargetThanHighIndex+1;
				}else{
					tempiso = sortArr[lowListIndex].iso;
					if(tempiso.gridX>iso.gridX){
						tempIndex = limitTargetThanHighIndex+1;
					}else
					tempIndex = limitTargetThanLowIndex - 1;
				}
				if(tempIndex == isoIndex) return;
				tempContainer.setChildIndex(iso,tempIndex);
				
			/*	tempIndex = limitTargetThanHighIndex+1;
				if(tempIndex == isoIndex) return;
				if(tempIndex>isoIndex) {
					tempContainer.setChildIndex(iso,tempIndex-1);
				}else{
					tempContainer.setChildIndex(iso,tempIndex);
				}*/
			}
		}
		//************************************************************* By CYang ************************************************************************************
		/**
		 * 判断区域是否解锁
		 * @param	x
		 * @param	y
		 */
		private function checkLockArea(x:Number, y:Number):void 
		{
				if(!_preIsoobject){
					_normalManager.mouseMoveLockArea(getGridPoint3D(x, y));
				}else  if(!(_preIsoobject as YIsoObject).mouseTipEnable && !(_preIsoobject as YIsoObject).isUnlock ){
					_normalManager.mouseMoveLockArea(getGridPoint3D(x, y));
				}else {
					_normalManager.outArea(); 
				}
		}

	}
}